package com.zy.rpc.common.codec;

import com.zy.rpc.common.Serializer.SerializerFactory;
import com.zy.rpc.common.ask.RpcRequest;
import com.zy.rpc.common.ask.RpcResponse;
import com.zy.rpc.common.constants.MsgType;
import com.zy.rpc.common.constants.ProtocolCons;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.apache.log4j.Logger;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * @author zy
 * @date 2023/5/14 19:05
 */
public class RpcDecoder extends ByteToMessageDecoder {
    private final static byte[] MAGIC_NUMBER= ProtocolCons.magic;
    private final static int VERSION = ProtocolCons.version;
    private static final Logger log=Logger.getLogger(RpcEncoder.class);
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() < 6) {
            return;
        }
        byte[] magic = new byte[4];
        in.readBytes(magic);
        if (!Arrays.equals(magic, MAGIC_NUMBER)) {
            throw new IllegalArgumentException("Invalid magic number");
        }
        byte version = in.readByte();
        if (version != VERSION) {
            throw new IllegalArgumentException("Invalid version: " + version);
        }
        byte serializer=in.readByte();
        if (in.readableBytes() < 4) {
            in.resetReaderIndex();
            return;
        }
        byte msgType=in.readByte();
        String messageId = in.readCharSequence(32, StandardCharsets.UTF_8).toString();
        int length = in.readInt();
        if (in.readableBytes() < length) {
            in.resetReaderIndex();
            return;
        }
        ByteBuf messageBuf = in.readBytes(length);
        byte[] messageBytes = new byte[length];
        messageBuf.readBytes(messageBytes);
        switch (MsgType.fromByte(msgType)) {
            case REQUEST:
                RpcRequest request = SerializerFactory.getDefaultSerializer().deserialize(RpcRequest.class,messageBytes);
                if (request != null) {
                    out.add(request);
                }
                break;
            case RESPONSE:
                RpcResponse response = SerializerFactory.getDefaultSerializer().deserialize(RpcResponse.class,messageBytes);
                if (response != null) {
                    out.add(response);
                }
                break;
        }

    }
}
